

class Router {
	constructor() {
		
		this.config = {
			type: 'navigateTo',
			url: '',
			delta: 1, 
			params: {}, 
			animationType: 'pop-in', 
			animationDuration: 300, 
			intercept: false, 
		}
		
		
		this.route = this.route.bind(this)
	}

	
	addRootPath(url) {
		return url[0] === '/' ? url : `/${url}`
	}

	
	mixinParam(url, params) {
		url = url && this.addRootPath(url)
		
		
		
		let query = ''
		if (/.*\/.*\?.*=.*/.test(url)) {
			
			query = uni.$u.queryParams(params, false);
			
			return url += "&" + query
		} else {
			
			query = uni.$u.queryParams(params);
			return url += query
		}
	}

	
	async route(options = {}, params = {}) {
		
		let mergeConfig = {}

		if (typeof options === 'string') {
			
			mergeConfig.url = this.mixinParam(options, params)
			mergeConfig.type = 'navigateTo'
		} else {
			mergeConfig = uni.$u.deepClone(options, this.config)
			
			mergeConfig.url = this.mixinParam(options.url, options.params)
		}
		
		if(params.intercept) {
			this.config.intercept = params.intercept
		}
		
		mergeConfig.params = params
		
		mergeConfig = uni.$u.deepMerge(this.config, mergeConfig)
		
		if (typeof uni.$u.routeIntercept === 'function') {
			
			const isNext = await new Promise((resolve, reject) => {
				uni.$u.routeIntercept(mergeConfig, resolve)
			})
			
			isNext && this.openPage(mergeConfig)
		} else {
			this.openPage(mergeConfig)
		}
	}

	
	openPage(config) {
		
		const {
			url,
			type,
			delta,
			animationType,
			animationDuration
		} = config
		if (config.type == 'navigateTo' || config.type == 'to') {
			uni.navigateTo({
				url,
				animationType,
				animationDuration
			});
		}
		if (config.type == 'redirectTo' || config.type == 'redirect') {
			uni.redirectTo({
				url
			});
		}
		if (config.type == 'switchTab' || config.type == 'tab') {
			uni.switchTab({
				url
			});
		}
		if (config.type == 'reLaunch' || config.type == 'launch') {
			uni.reLaunch({
				url
			});
		}
		if (config.type == 'navigateBack' || config.type == 'back') {
			uni.navigateBack({
				delta
			});
		}
	}
}

export default (new Router()).route